//
//  YKWebViewController.m
//  YKKit
//
//  Created by 马洪伟 on 16/1/13.
//  Copyright © 2016年 悦康动力（北京）科技有限公司. All rights reserved.
//

#import "YKWebViewController.h"

#define snapShotRequest @"snapShotRequest"
#define snapShotView @"snapShotView"

@interface YKWebViewController ()<UIWebViewDelegate, UIGestureRecognizerDelegate>
@property (strong, nonatomic) UIBarButtonItem *backBarButtonItem;
@property (strong, nonatomic) UIBarButtonItem *closeBarButtonItem;
@property (strong, nonatomic) UIBarButtonItem *spaceBarButtonItem;
@property (strong, nonatomic) UIPanGestureRecognizer *panGesture;
@property (strong, nonatomic) NSMutableArray *snapShotsArray;
@property (strong, nonatomic) UIView *currentSnapShotView;
@property (strong, nonatomic) UIView *prevSnapShotView;
@property (strong, nonatomic) UIView *paningBackgoundView;
@end

@implementation YKWebViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 修正后退手势
    self.navigationItem.backBarButtonItem = self.backBarButtonItem;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
    
    [self.view addSubview:self.webView];
    
    [self loadWebView];
}

// 调整左边导航栏
- (void)updateLeftNavigationBarArea {
    
    if ([self.webView canGoBack]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        self.panGesture.enabled = YES;
        [self.navigationItem setLeftBarButtonItems:@[self.spaceBarButtonItem,self.backBarButtonItem,self.closeBarButtonItem] animated:NO];
    } else {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        self.panGesture.enabled = NO;
        [self.navigationItem setLeftBarButtonItems:@[self.spaceBarButtonItem,self.backBarButtonItem] animated:NO];
    }
}

#pragma mark - 事件
- (void)doClickBackBarButtonItem {
    if ([self.webView canGoBack]) {
        [self.webView goBack];
    } else {
        [self doClickCloseBarButtonItem];
    }
}

- (void)doClickCloseBarButtonItem {
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - 请求
// 加载请求
- (void)loadWebView {
    if (_request) {
        [self.webView loadRequest:_request];
    }
}
// 请求处理
- (BOOL)handleRequest:(NSURLRequest *)request {
    BOOL shouldLoad = YES;
    
    NSString *urlString = [request.URL absoluteString];
    
    // 返回事件 定义
    if ([urlString hasSuffix:@"back"]) {
        [self doClickCloseBarButtonItem];
        return NO;
    }
    
    return shouldLoad;
}

#pragma mark - UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    BOOL shouldLoad = YES;
    
    if (_delegate && [_delegate respondsToSelector:@selector(webViewController:shouldStartLoadWithRequest:navigationType:)]) {
        shouldLoad = [_delegate webViewController:self shouldStartLoadWithRequest:request navigationType:navigationType];
    }
    
    if (shouldLoad) {
        shouldLoad = [self handleRequest:request];
    }
    
    if (shouldLoad) {
        switch (navigationType) {
            case UIWebViewNavigationTypeLinkClicked:
            case UIWebViewNavigationTypeFormSubmitted:
            case UIWebViewNavigationTypeOther: {
                [self pushCurrentSnapshotViewWithRequest:request];
                break;
            }
            default: {
                break;
            }
        }
        
        _request = request;
        _url = request.URL;
    }
    return shouldLoad;
}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    
    if (_delegate && [_delegate respondsToSelector:@selector(webViewControllerDidStartLoad:)]) {
        [_delegate webViewControllerDidStartLoad:self];
    }
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    [self updateLeftNavigationBarArea];
    
    if (_shouldShowWebContentTitle) {
        self.navigationItem.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    }
    
    if (_delegate && [_delegate respondsToSelector:@selector(webViewControllerDidFinishLoad:)]) {
        [_delegate webViewControllerDidFinishLoad:self];
    }
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    
    [self updateLeftNavigationBarArea];
    
    if (_delegate && [_delegate respondsToSelector:@selector(webViewController:didFailLoadWithError:)]) {
        [_delegate webViewController:self didFailLoadWithError:error];
    }
}

#pragma mark - panGesture / snapshot
- (void)doPanAction:(UIPanGestureRecognizer *)sender {
    if (sender != self.panGesture) {
        return;
    }
    CGPoint translation = [sender translationInView:self.webView];
    CGPoint location = [sender locationInView:self.webView];
    
    if (sender.state == UIGestureRecognizerStateBegan) {
        if (location.x <= 50 && translation.x >= 0) {
            [self startPopSnapshotView];
        }
    }
    else if (sender.state == UIGestureRecognizerStateChanged) {
        [self popSnapShotViewWithPanGestureDistance:translation.x];
    }
    else {
        [self endPopSnapShotView];
    }
}

- (void)startPopSnapshotView {
    if (![self.webView canGoBack]) {
        return;
    }
    
    //create a center of scrren
    CGPoint center = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);
    
    self.currentSnapShotView = [self.webView snapshotViewAfterScreenUpdates:YES];
    
    //add shadows just like UINavigationController
    self.currentSnapShotView.layer.shadowColor = [UIColor blackColor].CGColor;
    self.currentSnapShotView.layer.shadowOffset = CGSizeMake(3, 3);
    self.currentSnapShotView.layer.shadowRadius = 5;
    self.currentSnapShotView.layer.shadowOpacity = 0.75;
    //move to center of screen
    self.currentSnapShotView.center = center;
    
    self.prevSnapShotView = (UIView*)[[self.snapShotsArray lastObject] objectForKey:@"snapShotView"];
    center.x -= 60;
    self.prevSnapShotView.center = center;
    self.prevSnapShotView.alpha = 1;
    
    [self.view addSubview:self.prevSnapShotView];
    [self.view addSubview:self.paningBackgoundView];
    [self.view addSubview:self.currentSnapShotView];
}

- (void)popSnapShotViewWithPanGestureDistance:(CGFloat)distance{
    if (distance <= 0) {
        return;
    }
    
    CGPoint currentSnapshotViewCenter = CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)/2);
    currentSnapshotViewCenter.x += distance;
    CGPoint prevSnapshotViewCenter = CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)/2);
    prevSnapshotViewCenter.x -= (CGRectGetWidth(self.view.bounds) - distance)*60/CGRectGetWidth(self.view.bounds);
    
    self.currentSnapShotView.center = currentSnapshotViewCenter;
    self.prevSnapShotView.center = prevSnapshotViewCenter;
    self.paningBackgoundView.alpha = (CGRectGetWidth(self.view.bounds) - distance)/CGRectGetWidth(self.view.bounds);
}

- (void)endPopSnapShotView{
    //prevent the user touch for now
    self.view.userInteractionEnabled = NO;
    
    if (self.currentSnapShotView.center.x >= CGRectGetWidth(self.view.bounds)) {
        // pop success
        [UIView animateWithDuration:0.2 animations:^{
            [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
            
            self.currentSnapShotView.center = CGPointMake(CGRectGetWidth(self.view.bounds)*3/2, CGRectGetHeight(self.view.bounds)/2);
            self.prevSnapShotView.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)/2);
            self.paningBackgoundView.alpha = 0;
        }completion:^(BOOL finished) {
            [self.prevSnapShotView removeFromSuperview];
            [self.paningBackgoundView removeFromSuperview];
            [self.currentSnapShotView removeFromSuperview];
            [self.webView goBack];
            [self.snapShotsArray removeLastObject];
            self.view.userInteractionEnabled = YES;
        }];
    } else {
        //pop fail
        [UIView animateWithDuration:0.2 animations:^{
            [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
            
            self.currentSnapShotView.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)/2);
            self.prevSnapShotView.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2-60, CGRectGetHeight(self.view.bounds)/2);
            self.prevSnapShotView.alpha = 1;
        }completion:^(BOOL finished) {
            [self.prevSnapShotView removeFromSuperview];
            [self.paningBackgoundView removeFromSuperview];
            [self.currentSnapShotView removeFromSuperview];
            self.view.userInteractionEnabled = YES;
        }];
    }
}

- (void)pushCurrentSnapshotViewWithRequest:(NSURLRequest *)request {
    
    if ([request.URL.absoluteString isEqualToString:@"about:blank"]) {
        return;
    }
    
    NSURLRequest *lastRequest = [[self.snapShotsArray lastObject] objectForKey:snapShotRequest];
    if (lastRequest) {
        if ([lastRequest.URL.absoluteString isEqualToString:request.URL.absoluteString]) {
            return;
        }
    }
    
    UIView *currentSnapshotView = [self.webView snapshotViewAfterScreenUpdates:YES];
    [self.snapShotsArray addObject:@{snapShotRequest:request,snapShotView:currentSnapshotView}];
}

#pragma mark - Setter Getter
- (UIWebView *)webView {
    if (!_webView) {
        _webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
        _webView.delegate = self;
        _webView.scalesPageToFit = YES;
        [_webView addGestureRecognizer:self.panGesture];
    }
    return _webView;
}

- (void)setUrl:(NSURL *)URL {
    if (URL) {
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
        request.timeoutInterval = 30;
        self.request = request;
    }
}

- (void)setRequest:(NSURLRequest *)request {
    _request = request;
    if (self.isViewLoaded) {
        [self loadWebView];
    }
}
// 如果需要自定义返回按钮，才使用此方法
- (UIBarButtonItem *)backBarButtonItem {
    if (!_backBarButtonItem) {
        CGRect rect = CGRectMake(0, 0, 18, 30);
        UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextClearRect(context, rect);
        CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
        CGContextSetStrokeColorWithColor(context, self.navigationController.navigationBar.tintColor.CGColor);
        UIBezierPath *path = [UIBezierPath bezierPath];
        path.lineWidth = 2;
        path.lineJoinStyle = kCGLineJoinRound;
        [path moveToPoint:CGPointMake(13, 5)];
        [path addLineToPoint:CGPointMake(2, 15)];
        [path addLineToPoint:CGPointMake(13, 25)];
        [path stroke];
        CGContextAddPath(context, path.CGPath);
        CGContextFillRect(context, rect);
        UIImage *backItemImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
        CGContextRef context2 = UIGraphicsGetCurrentContext();
        CGContextClearRect(context2, rect);
        CGContextSetFillColorWithColor(context2, [UIColor clearColor].CGColor);
        CGContextSetStrokeColorWithColor(context2, [self.navigationController.navigationBar.tintColor colorWithAlphaComponent:0.5].CGColor);
        UIBezierPath *path2 = [UIBezierPath bezierPath];
        path2.lineWidth = 2;
        path2.lineJoinStyle = kCGLineJoinRound;
        [path2 moveToPoint:CGPointMake(13, 5)];
        [path2 addLineToPoint:CGPointMake(2, 15)];
        [path2 addLineToPoint:CGPointMake(13, 25)];
        [path2 stroke];
        CGContextAddPath(context2, path2.CGPath);
        CGContextFillRect(context2, rect);
        UIImage *backItemHlImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [backButton setTitleColor:self.navigationController.navigationBar.tintColor forState:UIControlStateNormal];
        [backButton setTitleColor:[self.navigationController.navigationBar.tintColor colorWithAlphaComponent:0.5] forState:UIControlStateHighlighted];
        [backButton.titleLabel setFont:[UIFont systemFontOfSize:17]];
        [backButton setTitle:@"返回" forState:UIControlStateNormal];
        [backButton setImage:backItemImage forState:UIControlStateNormal];
        [backButton setImage:backItemHlImage forState:UIControlStateHighlighted];
        [backButton addTarget:self action:@selector(doClickBackBarButtonItem) forControlEvents:UIControlEventTouchUpInside];
        [backButton sizeToFit];

        _backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    }
    return _backBarButtonItem;
}

- (UIBarButtonItem *)closeBarButtonItem {
    if (!_closeBarButtonItem) {
        _closeBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(doClickCloseBarButtonItem)];
    }
    return _closeBarButtonItem;
}

- (UIBarButtonItem *)spaceBarButtonItem {
    if (!_spaceBarButtonItem) {
        _spaceBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
        _spaceBarButtonItem.width = -8;
    }
    return _spaceBarButtonItem;
}

- (UIPanGestureRecognizer *)panGesture {
    if (!_panGesture) {
        _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doPanAction:)];
    }
    return _panGesture;
}

- (NSMutableArray *)snapShotsArray {
    if (!_snapShotsArray) {
        _snapShotsArray = [NSMutableArray arrayWithCapacity:0];
    }
    return _snapShotsArray;
}

- (UIView *)paningBackgoundView {
    if (!_paningBackgoundView) {
        _paningBackgoundView = [[UIView alloc] initWithFrame:self.view.bounds];
        _paningBackgoundView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
    }
    return _paningBackgoundView;
}

@end
